using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Collections;

using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Net.Sockets;
using BrainTechLLC;

namespace Mud.EmlenMudMain
{
    [Serializable]
    public class Spell : GameThingBaseClass
    {
        public Spell()
        {
            gsn = 0;
            slot = 0;
        }
        public Spell(int _slot, int _gsn, string _spell_name, string _secondary_name)
        {
            slot = _slot; gsn = _gsn; Name = new NameAndDescription() { Name = _spell_name, FriendlyUniqueName = _spell_name }; secondaryName = _secondary_name;
        }
        public Spell(int _slot, GeneralSN _gsn, string _spell_name, string _secondary_name)
        {
            slot = _slot; gsn = (int)_gsn; Name = new NameAndDescription() { Name = _spell_name, FriendlyUniqueName = _spell_name }; secondaryName = _secondary_name;
        }
        private string secondaryName = "";

        public string SecondaryName
        {
            get { return secondaryName; }
            set { secondaryName = value; }
        }
        private int slot = 0;			/* Slot, unused! */

        public int Slot
        {
            get { return slot; }
            set { slot = value; }
        }
        private int gsn = 0;			/* General slot number.  internal use */

        public int Gsn
        {
            get { return gsn; }
            set { gsn = value; }
        }
        private SpellTargets spellType = SpellTargets.IGNORE;		/* Offensive, defensive, etc... */

        public SpellTargets SpellType
        {
            get { return spellType; }
            set { spellType = value; }
        }
        private SpellFlags spellBits = SpellFlags.NONE;		/* SPELL_SUMMON, etc.. */

        public SpellFlags SpellBits
        {
            get { return spellBits; }
            set { spellBits = value; }
        }
        private int spellLevel = 0;		/* Minimum level to cast this spell */

        public int SpellLevel
        {
            get { return spellLevel; }
            set { spellLevel = value; }
        }
        private string prereq1 = string.Empty;		/* Spell prereq #1 */

        public string Prereq1
        {
            get { return prereq1; }
            set { prereq1 = value; }
        }
        private string prereq2 = string.Empty;		/* Spell prereq #2 */

        public string Prereq2
        {
            get { return prereq2; }
            set { prereq2 = value; }
        }
        private string nounDamage = "";		/* Noun damage for offensive combat spells */

        public string NounDamage
        {
            get { return nounDamage; }
            set { nounDamage = value; }
        }
        private string actToCh1 = "";		/* Shown to character when he/she casts */

        public string ActToCh1
        {
            get { return actToCh1; }
            set { actToCh1 = value; }
        }
        private string actToCh2 = "";		// Just another line to show to public string

        public string ActToCh2
        {
            get { return actToCh2; }
            set { actToCh2 = value; }
        }
        private string actToVict1 = "";	/* To victim */

        public string ActToVict1
        {
            get { return actToVict1; }
            set { actToVict1 = value; }
        }
        private string actToVict2 = "";

        public string ActToVict2
        {
            get { return actToVict2; }
            set { actToVict2 = value; }
        }
        private string actToNotvict1 = "";	/* To everyone in currentRoom besides char + vict */

        public string ActToNotvict1
        {
            get { return actToNotvict1; }
            set { actToNotvict1 = value; }
        }
        private string actToNotvict2 = "";

        public string ActToNotvict2
        {
            get { return actToNotvict2; }
            set { actToNotvict2 = value; }
        }
        private StatTypes location = StatTypes.None;		/* Modifies this location (str, dex, etc) */

        public new StatTypes Location
        {
            get { return location; }
            set { location = value; }
        }
        private string duration = "";		/* Needs to be a string so we can have vars */

        public string Duration
        {
            get { return duration; }
            set { duration = value; }
        }
        private string modifier = "";		/* Amount to modify location */

        public string Modifier
        {
            get { return modifier; }
            set { modifier = value; }
        }
        private long bitvector = (long)EffectType.NONE;		/* EffectTypeFlags for modification */

        public long Bitvector
        {
            get { return bitvector; }
            set { bitvector = value; }
        }
        private string damage = "";		/* If combat spell, how much dam (w/vars) */

        public string Damage
        {
            get { return damage; }
            set { damage = value; }
        }
        private int mana = 1;			/* Minimum Mana cost */

        public int Mana
        {
            get { return mana; }
            set { mana = value; }
        }
        private ManaType mana_type = ManaType.AnyManaType;		/* Mana type */

        public ManaType Mana_type
        {
            get { return mana_type; }
            set { mana_type = value; }
        }
        private int casting_time = 1000;		/* Casting delay time. 10 = 1 combat round */

        public int Casting_time
        {
            get { return casting_time; }
            set { casting_time = value; }
        }
        private CharPosition positionRequired = CharPosition.fighting;		/* Position you must be in to cast */

        public CharPosition PositionRequired
        {
            get { return positionRequired; }
            set { positionRequired = value; }
        }
        private string wearOffMsg = "";		/* When the spell wears off, this msg is disp'd */

        public string WearOffMsg
        {
            get { return wearOffMsg; }
            set { wearOffMsg = value; }
        }
        private int createsObj;		/* Creates this object vnum */

        public int CreatesObj
        {
            get { return createsObj; }
            set { createsObj = value; }
        }
        private int[] vals = new int[10];		/* Uses these values on creates_obj... UNUSED! */

        public int[] Vals
        {
            get { return vals; }
            set { vals = value; }
        }
        /* -9 means use creates_obj base value */
        private int minInt;	/* Minimum public int to learn the spell fully */

        public int MinInt
        {
            get { return minInt; }
            set { minInt = value; }
        }
        private int minWis;	/* Minimum wis to learn the spell fully */

        public int MinWis
        {
            get { return minWis; }
            set { minWis = value; }
        }
        /* These flags are used as con/str for skills */
        private string linkedTo = "";		/* Linked to this spell; when you cast spell
				   A, spell B is also cast.  */

        public string LinkedTo
        {
            get { return linkedTo; }
            set { linkedTo = value; }
        }


        public static bool Load(int inVersion)
        {
            if (SerializeSpellsIn(inVersion) == false)
            {
                FileStream fs = null;
                string szFullFilePathName = EmlenMud.HostPathnameToMudDirectory + "\\" + MiscConstants.DataFileDirectory + "\\spells.dat";
                try
                {
                    fs = new FileStream(szFullFilePathName, FileMode.Open, FileAccess.Read);
                }
                catch (IOException ex) { EmlenMud.LogError("Error reading " + szFullFilePathName + ": ", ex, LogType.Always); return false; }

                StreamReader sr = new StreamReader(fs);
                List<Spell> rg = EmlenMud.Oldschool.load_spells_old_format(sr);

                sr.Close();
                fs.Close();

                for (int n = 0; n < rg.Count; n++)
                {
                    Spell spell = (Spell)rg[n];
                    //spell.AssignEmlenMud(EmlenMud);
                    spell.AddNewSpell();
                }

                SerializeSpellsOut(inVersion);
            }
            return true;
        }

        public static bool Save(int outVersion)
        {
            return SerializeSpellsOut(outVersion);
        }

        public static bool SerializeSpellsIn(int inVersion)
        {
#if NO_SILVERLIGHT
            string szFName = EmlenMud.HostPathnameToMudDirectory + "\\" + MiscConstants.DataFileDirectory + "\\" + typeof(Spell).Name.ToString() + inVersion.ToString();
            Object o = SerializationHelper.SerializeObjectIn(szFName);
            if (o == null) return false;
            if (o is ArrayList)
            {
                ArrayList rgIn = (ArrayList)o;
                EmlenMud.WorldTemplates.SpellList.Clear();
                EmlenMud.WorldTemplates.htSpellListByName.Clear();
                EmlenMud.WorldTemplates.htSpellListByGSN.Clear();
                foreach (Spell spell in rgIn)
                {
                    //spell.AssignEmlenMud(EmlenMud);
                    spell.AddNewSpell();
                }
                return true;
            }
            return false;
#else 
            return true;
#endif
        }

        public static bool SerializeSpellsOut(int outVersion)
        {
#if NO_SILVERLIGHT
            string szFName = EmlenMud.HostPathnameToMudDirectory + "\\" + MiscConstants.DataFileDirectory + "\\" + typeof(Spell).Name.ToString() + outVersion.ToString();
            return SerializationHelper.SerializeObjectOut(EmlenMud.WorldTemplates.SpellList, szFName, true);
#else 
            return true;
#endif
        }


        public bool AddNewSpell()
        {
            if (EmlenMud.WorldTemplates.htSpellListByGSN[gsn] == null)
            {
                EmlenMud.WorldTemplates.SpellList.Add(this);
                EmlenMud.WorldTemplates.htSpellListByName[ShortName] = this;
                EmlenMud.WorldTemplates.htSpellListByGSN[gsn] = this;
                return true;
            }
            return false;
        }



    }
}
